package pimcontr;

/**
 * Klasse um die Terminliste zu speichern bzw. zu laden. Vermutlich wird hier auch die Erinnerungsfunktion implementiert
 * 
 *
 */
import java.text.SimpleDateFormat;
import java.util.*;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import pimgui.PimGui;
import pimmodel.*;

public class TerminManager extends PimManager{
	
	private TerminList termine;
	private ITerminList erinnerung;
	private TerminList wiederholung;
	public Map<String, String> map;
	
	public TerminManager(){
		termine=new TerminList();
		erinnerung=new TerminList();
		wiederholung=new TerminList();
		map = new HashMap<String, String>();
		
	}
	
	public void speichern() throws FileNotFoundException, IOException{
	
		termine.speichern("terminliste.dat");
		
		wiederholung.speichern("wiederholungsliste.dat");
		
	}
	
	public void laden() throws ClassNotFoundException, IOException{
		
		termine.laden("terminliste.dat");
	
		wiederholung.laden("wiederholungsliste.dat");
		maperzeugen();
		try {
			erinnernalle();
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
	@Override
	public void drucken() {
		// TODO Auto-generated method stub
		
	}
	/**
	 * Methode zum hinzufuegen eines Termins
	 */
	@Override
	public void hinzufuegen(IPimDaten adddaten) {
		termine.terminHinzufuegen((ITermin) adddaten);
		
		
		// TODO Auto-generated method stub
		
	}
	/**
	 * Methode zum loeschen eines Termins
	 */
	@Override
	public void loeschen(IPimDaten loeschdaten) {
		termine.terminLoeschen((ITermin)loeschdaten);
		// TODO Auto-generated method stub
		
	}
	/**
	 * Methode zum aendern eines Termins
	 */
	@Override
	public void aendern(IPimDaten beardaten, IPimDaten orgdaten) {
		termine.terminErsetzen( (ITermin)beardaten, (ITermin)orgdaten );
		
	}
	
	public void loeschen(int index){
		termine.getTerminliste().remove(index);
		
	}
	/**
	 * 
	 * Suchfunktion
	 **/
	public ITermin suchen(String suchname){
		ITermin gefunden=new Termin();
		int index=termine.terminNameSuchen(suchname);
		gefunden=termine.getTerminliste().get(index);
		return gefunden;
	}
	/**
	 * 
	 * Suchfunktion
	 **/
	public ITermin suchenTer(ITermin suchTermin){
		ITermin gefunden=new Termin();
		int index=termine.terminSuchen(suchTermin);
		gefunden=termine.terminLiefern(index);
		return gefunden;
	}
	/**
	 * Methode die die ganze Liste durchgeht und schaut an welche Termin man erinnert werden soll
	 * 
	 */
	public void erinnernalle() throws Exception{
		int i=0;
		erinnerung=new TerminList();
		while (i<termine.getTerminliste().size()){
			if (termine.getTerminliste().get(i).getErinnerung()){
				erinnernTermin(termine.getTerminliste().get(i));
			}
			
			i++;
		}
		erinnerung.sortieren();
		
		
		//System.out.println("Erinnerung"+erinnerung.toString()+"Ende");
	}
	/**
	 * Fuegt der Erinnerungsliste den entsprechenden Termin zu
	 * @param erTermin Termin an den man erinnert werden will
	 */
	public void erinnernTermin(ITermin erTermin) throws Exception{
		ITermin neu=new Termin();
		Date altDate=erTermin.getDatum();
		neu.setName(erTermin.getName());
		neu.setBeschreibung(erTermin.getBeschreibung());
		neu.setErinnerung(erTermin.getErinnerung());
		neu.setErinnerungszeitpunkt(erTermin.getErinnerungszeitpunkt());
		neu.setWiederholung(erTermin.getWiederholung());
		neu.setWiederholungsintervall(erTermin.getWiederholungsintervall());
		neu.setOrt(erTermin.getOrt());
		neu.setStrasse(erTermin.getStrasse());
	
		Date erDate=datumerinermitteln(altDate,erTermin.getErinnerungszeitpunkt());
		neu.setDatum(erDate);
		erinnerung.terminHinzufuegen(neu);
		
	}

	/**
	 * Methode die das DAtum ermittelt wann man erinnert werden soll
	 * @param datum des TErmins
	 * @param erinnerungszeitpunkt Wann soll man erinnert werden
	 */
	private Date datumerinermitteln(Date datum,int erinnerungszeitpunkt) {
		GregorianCalendar cal=new GregorianCalendar();
		cal.setTime(datum);
		if(erinnerungszeitpunkt==1){
		cal.add(Calendar.DAY_OF_MONTH, -1);
		}else if(erinnerungszeitpunkt==3){
		cal.add(Calendar.DAY_OF_MONTH, -3);
		}else if(erinnerungszeitpunkt==7){
		cal.add(Calendar.DAY_OF_MONTH, -7);	
		}
		
		
		return cal.getTime();
	}

	/**
	 * Methode die die Liste nach Datum durchgeht und die Termin die wiederholt werden soll wiederholt
	 * @param datum aktuelles Datum
	 */
	public void wiederTerminalle(Date datum) throws Exception{
		//int i=0;
		SimpleDateFormat df= new SimpleDateFormat("dd.MM.yyyy");
		
		
		int m=termine.getTerminliste().size();
		for (int i=0;i<termine.getTerminliste().size();i++){
			
			String vergleich=df.format(termine.getTerminliste().get(i).getDatum());
			String ausgabedatum=df.format(datum);
			//if (vergleich.equals(ausgabedatum)){
			//	if (termine.getTerminliste().get(i).getWiederholung()==true){
			//		System.out.println(termine.getTerminliste().get(i));
			//		wiederTermin(termine.getTerminliste().get(i));
			//	}
			//}
			if(vergleich.compareTo(ausgabedatum)<=0){
				if (termine.getTerminliste().get(i).getWiederholung()==true){
							
							wiederTermin(termine.getTerminliste().get(i));
				}
			}
			int gleich=ausgabedatum.compareTo(vergleich);
			//System.out.println(vergleich+ ausgabedatum+gleich);
//			while (gleich<0){
//				if (termine.getTerminliste().get(i).getWiederholung()==true){
//					try {
//						
//						wiederTermin(termine.getTerminliste().get(i));
//						
//					} catch (Exception e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//				}
//
//			}
			
			//if (termine.getTerminliste().get(i).getDatum().equals(datum)){
			
		}
//		while (termine.getTerminliste().get(i).getDatum().equals(datum)&&i<termine.getTerminliste().size()){
//			Termin neu=termine.getTerminliste().get(i);
//			
//			if (termine.getTerminliste().get(i).isWiederholung()==true){
//				wiederTermin(termine.getTerminliste().get(i));
//			}
//			
//			i++;
//		}
	}

	/**
	 * Erstellt einen Wiederholungstermin
	 * @param altTermin Termin der zu wiederholen ist
	 * @throws Exception
	 */
	public void wiederTermin(ITermin altTermin) throws Exception{
		SimpleDateFormat df= new SimpleDateFormat("dd.MM.yyyy");
		ITermin alt=altTermin;
		Date altdate=alt.getDatum();
		Date neuDate=datumermitteln(altdate,altTermin.getWiederholungsintervall());
		Termin neu=new Termin();
		neu.setName(alt.getName());
		neu.setBeschreibung(alt.getBeschreibung());
		neu.setDatum(neuDate);
		neu.setHausnummer(alt.getHausnummer());
		neu.setErinnerung(alt.getErinnerung());
		neu.setErinnerungszeitpunkt(alt.getErinnerungszeitpunkt());
		neu.setWiederholung(true);
		neu.setWiederholungsintervall(alt.getWiederholungsintervall());
		neu.setOrt(alt.getOrt());
		neu.setStrasse(alt.getStrasse());
		
		int index=0;
		boolean vergleich=false;
		for (int i=0;i<termine.getTerminliste().size();i++){
			if (termine.getTerminliste().get(i).getName().equals(neu.getName())){
				if(df.format(termine.getTerminliste().get(i).getDatum()).equals(df.format(neu.getDatum()))){
					vergleich=true;
				}
			}
		}
		try{
			
			if (map.get(neu.getName()+df.format(neu.getDatum()))!=null){
				index=1;
			}
		}catch (Exception e){
			
		}
		if (termine.getTerminliste().contains(neu)){
			
		}else if(vergleich ==false){
		wiederholung.terminHinzufuegen(neu);
		//System.out.println(wiederholung.toString());
		//System.out.println(wiederholung.toString());
		hinzufuegen(neu);
		}
	}
	/**
	 * Methode die das Datum fuer den Wiederholungstermin ermittelt
	 * @param datum des Termins
	 * @param wiederholung Wann soll der Termin wiederholt werden
	 */
	public Date datumermitteln(Date datum,int wiederholung){
		GregorianCalendar cal=new GregorianCalendar();
		cal.setTime(datum);
		if(wiederholung==1){
		cal.add(Calendar.DAY_OF_MONTH, 1);
		}else if(wiederholung==7){
		cal.add(Calendar.DAY_OF_MONTH, 7);
		}else if(wiederholung==30){
		cal.add(Calendar.MONTH ,1);
		}else{
		cal.add(Calendar.YEAR, 1);	
		}
		
		
		return cal.getTime(); 
	}
	/**
	 * Methode die ein Stringarry erstellt mit den Namen der Termin fuer die ausgabe in der gui
	 * @param date aktuelles Datum
	 * @return gibt ein Array mit den Terminnamen zurueck
	 */
	public String[] terminausgabeNachDatum(Date date) {
	
		Map<String, String> map = new HashMap<String, String>();
		//Object[] aufgabenarray= terminliste.getTerminliste().toArray();
		String[]terminname=new String[termine.size()+1];
		terminname[0]=PimGui.getResourceBundle().getString("pimgui25")/*"Alle Daten anzeigen"*/;
		int j=1;
		SimpleDateFormat df= new SimpleDateFormat("dd.MM.yyyy");
		
		//System.out.println("Hier"+termine.toString()+"ende");
		
		
		
		for (int i=0;i<termine.size();i++){
			//System.out.println(date.toString()+"sdass"+termine.getTerminliste().get(i).getDatum());
		
				
			//	terminname[j]=termine.getTerminliste().get(i).getName();
			//	j++;
			//}
			//System.out.println()
			String vergleich=df.format(date);
			String ausgabe=df.format(termine.getTerminliste().get(i).getDatum());
			
			//System.out.println(termine.getTerminliste().get(i).toString());
			if (vergleich.equals(ausgabe)){
				//map.put(termine.getTerminliste().get(i).getName(), i);
				terminname[j]=termine.getTerminliste().get(i).getName();
				j++;
			}
			
			
			//if (df.format(date).equals(df.format(termine.getTerminliste().get(i).getDatum()))){
		}
		return terminname;
		// TODO Auto-generated method stub
	}
	/**
	 * Methode die eine Map fuellt mit den Indexen der Terminen
	 * um das Suchen zu vereinfachen, dies geschieht mit der Kombination von Terminnamen und Termindatum
	 */
	public void maperzeugen() {
		
		for (int i=0;i<termine.size();i++){

			SimpleDateFormat df= new SimpleDateFormat("dd.MM.yyyy");
			//System.out.println(termine.getTerminliste().get(i).getName()+df.format(termine.getTerminliste().get(i).getDatum()));
			map.put(termine.getTerminliste().get(i).getName()+df.format(termine.getTerminliste().get(i).getDatum()), i+"");
			
		}
		
		
	}
	
	//get- und set-Methoden
	
	public Map<String, String> getMap() {
		return map;
	}

	public void setMap(Map<String, String> map) {
		this.map = map;
	}
	
	public TerminList getTermine() {
		return termine;
	}

	public void setTermine(TerminList termine) {
		this.termine = termine;
	}
	
	
	public ITerminList getErinnerung() {
		return erinnerung;
	}

	public void setErinnerung(ITerminList erinnerung) {
		this.erinnerung = erinnerung;
	}
	
	
	public ITerminList getWiederholung() {
		return wiederholung;
	}

	public void setWiederholung(TerminList wiederholung) {
		this.wiederholung = wiederholung;
	}

	/**
	 * Methode um die komplette Liste als String auszugeben
	 */
	public String toString(){
		return termine.toString();
	}
	
	


}
